// ----------------------------------------------------------------------------
// mutex.cpp
// ----------------------------------------------------------------------------
#include <fw/base/concurrent/mutex.h>
#include <fw/base/core/macros.h>
#if   defined(FW_TARGET_WINDOWS)
#include <fw/base/concurrent/_Windows/mutex_impl.windows.h>
#elif defined(FW_TARGET_APPLE)
#include <fw/base/concurrent/_MacOSX/mutex_impl.apple.h>
#else
#error		"未対応のプラットフォームです."
#endif

namespace fw
{
	Mutex::Mutex(const char* name)
	: m_impl(0)
	, m_locked(false)
	{
		m_impl = new MutexImpl(name);
		FW_ASSERT(m_impl);
	}
	
	Mutex::~Mutex()
	{
		FW_ASSERT(m_impl);
		FW_ASSERT(m_locked == false, "Unlock before destruct.");
		if(m_impl){delete m_impl; m_impl = 0;}
	}

	void Mutex::Lock()
	{
		FW_ASSERT(m_impl);
		bool ret = m_impl->Lock();
		FW_ASSERT(ret==true, "Lock failure.");
		FW_UNUSED(ret);
		
		FW_ASSERT(m_locked == false);
		m_locked = true;
	}
	
	bool Mutex::TryLock()
	{
		FW_ASSERT(m_impl);
		bool ret = m_impl->TryLock();
		if(ret)
		{
			FW_ASSERT(m_locked == false);
			m_locked = true;
			return true;
		}
		return false;
	}
	
	void Mutex::Unlock()
	{
		FW_ASSERT(m_impl);
		FW_ASSERT(m_locked == true);
		m_locked = false;
		if(m_impl->Unlock())
		{
			return;
		}
		FW_ASSERT(0, "Unlock failure.");
	}
	
} // namespace fw 
